#!/usr/bin/env python
#coding=utf-8

#This file for XCMD, created by OpenThings.
#Using this to automate the test procedure.
#Author: openthings@163.com. copyright&GPL V2.
#Last modified 2014-12-11.

import sys
import threading
from socket import *
from time import *

import xc_serial
import pynmea2

print("  ==================================================")
print("  *   Welcome to GPS-NMEA 0180 Receiver   !        *")
print("  *      For nodeMCU based ESP8266 SoC.               *")
print("  *     By openthings@163.com. 2014-10.            *")
print("  *------------------------------------------------*")

xc_serial.isSimulate = 0
#xc_serial.port = '/dev/ttyUSB0'
xc_serial.port = '/dev/tty.wchusbserial1410'
#xc_serial.port = '/dev/tty.usbserial'
xc_serial.baudrate = 9600

print "   Open Serial at: ",xc_serial.port,",",xc_serial.baudrate
print "   $df:dofile,$lf:upload file,$lfall:upload all lua."
print("  *================================================*")

xc_serial.serialopen()

#通知线程是否继续运行。
IS_RUN = 1

#============================================
#多线程执行串口访问，去除阻塞现象。
def uartclient():
	global addr
	while True: 
		if IS_RUN == 0:
			break
		#data = xc_serial.waitresult()
		data = xc_serial.ser.readline()
		if not data:
		    break 
		print ">>",data.strip()
        ongpsdata(data)

def uartstart():
	t_uart = threading.Thread(target=uartclient,args=())
	t_uart.setDaemon(True)
	t_uart.start()

#============================================
#解析GPS的NMEA0180数据格式。
def ongpsdata(strnmea):
    msg = pynmea2.parse(strnmea)
    print("Location:",msg.lat,",",msg.lon)

#============================================
def exeCMD(strCMD):
	if (strCMD==""):	#主机命令。
		print ">"
	elif (strCMD.find("~")==0):	#主机命令。
		strResult = exeHost(strCMD)
		return 
	elif(strCMD.find("?")==0):	#主机命令。
		exeHost_help(strCMD)
	else:
		exeRemote(strCMD)
		#strResult = xc_serial.xcmd_all(strCMD)
		return

#执行远程指令。
def exeRemote(strRemote):
	if (strRemote[0]!='#'): 		#注释行，跳过。
		xc_serial.writeln(strRemote)	#发送到网络。

#执行远程指令-阻塞等待返回值。
def exeRemoteSync(strRemote):
	strResult = xc_serial.xcmd_all(strCMD)	#发送到网络。
	return strResult
	
#执行主机的操作。
def exeHost(strCMD):
	if (strCMD.upper()=="~LOADFILE") or (strCMD.upper()=="~LF"):
		exeHost_lua_upload()
	elif (strCMD.upper()=="~DOFILE") or (strCMD.upper()=="~DF"):
		exeHost_lua_dofile()
	elif (strCMD.upper()=="~DOCONFIG") or (strCMD.upper()=="~DC"):
		exeHost_lua_doconfig()
	elif (strCMD.upper()=="~INITRESET") or (strCMD.upper()=="~RESET"):
		exeHost_lua_initreset()
	elif (strCMD.upper()=="~RECONFIG"):
		exeHost_lua_initreset()
	elif (strCMD.upper()=="~LOADFILEALL") or (strCMD.upper()=="~LFALL"):
		exeHost_lua_uploadall()
	elif (strCMD.upper()=="~LOADFILEGPS") or (strCMD.upper()=="~LFGPS"):
		exeHost_lua_uploadgpio()
	elif (strCMD.upper()=="~LOADFILETOOL") or (strCMD.upper()=="~LFTOOL"):
		exeHost_lua_uploadtool()
	else:
		print "Invalid CMD: ",strCMD
	return "HOSTCMD:",strCMD

#============================================
def exeHost_lua_initreset():
	print("Empty init.lua file...")
	lua_upload("../init0.lua","init.lua")

def exeHost_lua_reconfig():
	print("Reload apconfig.lua file...")
	lua_upload("../apconfig.lua","apconfig.lua")

def exeHost_lua_uploadgps():
	print("Reload uartnmea.lua for gps file...")
	lua_upload("../uartnmea.lua","uartnmea.lua")

def exeHost_lua_uploadall():
	lua_upload("../init.lua","init.lua")
	lua_upload("../uartnmea.lua","uartnmea.lua")
	lua_upload("../server.lua","server.lua")

def exeHost_lua_uploadtool():
	lua_upload("../uartnmea.lua","uartnmea.lua")
	lua_upload("../server.lua","server.lua")

#run a lua file on remote nodemcu.
def exeHost_lua_dofile():
	luafilehost = raw_input('Run LUA file pathname:') 
	if (luafilehost==""):
		print "LUA file is Empty."
		return
	lua_dofile(luafilehost)

#run a lua config on remote nodemcu.
def exeHost_lua_doconfig():
	lua_dofile("../config.lua")
	
#============================================
#loadluafile into nodemcu.
def exeHost_lua_upload():
	luafilehost = raw_input('Input LUA file pathname:') 
	if (luafilehost==""):
		print "LUA file is Empty."
		return
		
	luafileremote = raw_input('Input Remote file name:') 
	if (luafileremote==""):
		print "LUA file is Empty."
		return
	lua_upload(luafilehost,luafileremote)


#upload a lua file to remote nodemcu.
def lua_upload(luahost,luaremote):	
	print "Uploading:",luahost,",",luaremote
	print "=========================================="
	luafilehost = open(luahost,'r')
	strRemote = "file.open(\""+luaremote+"\",\"w\")"
	print strRemote
	strResult = exeRemote(strRemote)
	sleep(0.5)
	exeRemote("tmr.wdclr()")
	sleep(0.5)
	for  strlualine in  luafilehost: 
		strlualine = strlualine.strip('\n') 
		strlualine = strlualine.replace("\\","\\\\")
		strlualine = strlualine.replace("\"","\\\"")
		strlualine = "file.writeline(\'"+strlualine+"\')"
		print strlualine
		strLast = exeRemote(strlualine)
		sleep(0.5)
	strRemote = "file.flush()"
	print strRemote
	exeRemote(strRemote)
	sleep(2)
	strRemote = "file.close()"
	print strRemote
	exeRemote(strRemote)	
	luafilehost.close()
	sleep(2)
	print "===Upload LUA finished.===================="
	print ""

#run a lua file as dofile() in lua.
#将本地LUA文件在远端运行,通过逐行发送来进行。
def lua_dofile(luahost):
	print "Remote Run:",luahost
	print "=========================================="
	luafilehost = open(luahost,'r')
	for  strlualine in  luafilehost: 
		#print strlualine
		strLast = exeRemote(strlualine)
		sleep(1)
	luafilehost.close()
	print "===Run LUA at remote finished.============"
	print ""
		
#============================================
def waitinput():
	while True:
		xcmd = raw_input('') 
		if (xcmd.upper()=="EXIT"):
			IS_RUN = 0
			xc_serial.serialclose()	
			print "[xconsole for UART] exited."
			exit()
		exeCMD(xcmd)
	
def processcmd():
	if (len(sys.argv)<=1):
		return
	for arg in sys.argv:
		print arg
	if sys.argv[1].upper()=="LFALL":
		print "Begin upload all LUA..."
		exeHost_lua_uploadall()
	exit()
	
#============================================
if __name__ == "__main__":
    uartstart()
    processcmd()
    waitinput()

#======================================

